package it.unibo.imola.parser.visitor.entity;

import it.unibo.imola.utils.ToStringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CustomOperatorCallStatement extends CallStatement {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	public CustomOperatorCallStatement(String name, ToolBox toolbox) {
		super(name, toolbox);
	}
	
	@Override
	public boolean check(GlobalEnvironment gEnv, Environment env) throws Exception {
		
		if(super.check(gEnv, env)){
			// qui vado prima a vedere se c'è una definizione con quel nome e con
			// quei parametri
			
			if (gEnv.getDefinitions().containsKey(name)) {
				StatementSequence statementSequence = gEnv.getDefinitions().get(name);
				Class<?>[] formalParameterTypes = statementSequence.getDefinition().getFormalParameterTypes();
				boolean compatible = true;
				
				if(formalParameterTypes.length != actualParameterType.length) {
					compatible = false;
				}
				for (int i = 0; i < formalParameterTypes.length; i++) {
					if (formalParameterTypes[i] != actualParameterType[i]) {
						if (logger.isDebugEnabled())
							logger.debug("formal[" + i + "]=" + formalParameterTypes[i].getSimpleName() + " not equal to actual[" + i + "]=" + actualParameterType[i].getSimpleName());
						compatible = false;
					}
				}

				if (compatible){
					return true;
				}
			}
		}

		if (logger.isDebugEnabled())
			logger.debug(name + ": check:  GlobalEnvironment does not contains DEFINITION \"" + name + "\" " + ToStringUtils.toString(actualParameterType));
		throw new Exception(name + ": check:  GlobalEnvironment does not contains DEFINITION \"" + name + "\" " + ToStringUtils.toString(actualParameterType));
	}
	
	@Override
	public void exec(GlobalEnvironment gEnv, Environment env) throws Exception {
		super.exec(gEnv, env);
		
		if (gEnv.getDefinitions().containsKey(name)) {
			StatementSequence statementSequence = gEnv.getDefinitions().get(name);
			statementSequence.setActualParameters(unboxedActualParameters);
			statementSequence.exec(gEnv,env);
			return;
		}

		if (logger.isDebugEnabled())
			logger.debug(name + ": exec: GlobalEnvironment does not contains DEFINITION \"" + name + "\" " + ToStringUtils.toString(actualParameterType));
		throw new Exception(name + ": exec: GlobalEnvironment does not contains DEFINITION \"" + name + "\" " + ToStringUtils.toString(actualParameterType));
	}

}
